package com.tengju.bff.interfaces.covercharge.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.idanchuang.component.base.util.StringUtil;
import com.idanchuang.component.redis.util.RedisUtil;
import com.tengju.bff.interfaces.covercharge.constant.*;
import com.tengju.bff.interfaces.covercharge.entity.po.*;
import com.tengju.bff.interfaces.covercharge.entity.vo.*;
import com.tengju.bff.interfaces.covercharge.enums.ProfitTypeEnum;
import com.tengju.bff.interfaces.covercharge.mapper.ServiceRewardPunishDetailMapper;
import com.tengju.bff.interfaces.covercharge.mapper.ServiceTaskMapper;
import com.tengju.bff.interfaces.covercharge.service.*;
import com.tengju.bff.interfaces.covercharge.service.message.client.UserMessageClient;
import com.tengju.bff.interfaces.covercharge.util.DateTimeUtils;
import com.tengju.bff.interfaces.covercharge.util.OssUtil;
import com.tengju.user.domain.model.user.UserIdCode;
import com.tengju.user.domain.model.user.UserInfo;
import com.tengju.user.domain.model.user.UserInfoRepository;
import com.tengju.user.domain.service.UserDocService;
import com.zoi7.component.core.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 奖惩明细表 服务实现类
 * </p>
 *
 * @author zhaoyi
 * @since 2020-12-16
 */
@Slf4j
@Service
public class ServiceRewardPunishDetailServiceImpl extends ServiceImpl<ServiceRewardPunishDetailMapper, ServiceRewardPunishDetail> implements IServiceRewardPunishDetailService {
//    @Resource
//    private UserInfoRepository userInfoRepository;
    @Resource
    private UserDocService userDocService;

//    @Resource
//    private BrandProviderLevelServer brandProviderLevelServer;

    @Resource
    private UserMessageClient userMessageClient;

    @Resource
    private IServiceAccountService serviceAccountService;

    @Resource
    private IServiceArrearDetailService serviceArrearDetailService;

    @Resource
    private IServiceCustomDetailService serviceCustomDetailService;

    @Resource
    private IServiceRewardPunishCategoryService serviceRewardPunishCategoryService;

    @Resource
    private ServiceTaskMapper serviceTaskMapper;

    @Resource
    private ITaskService taskService;

    private final static Integer SPLIT_MAX_NUM = 200;

    /**
     * 获取申请单信息
     *
     * @param adminPunishApplyQuery 请求参数
     * @return 返回结果
     */
    @Override
    public IPage<AdminPunishApplyVo> getApplyInfo(AdminPunishApplyQuery adminPunishApplyQuery) {
        //1、根据参数查询
        QueryWrapper<ServiceRewardPunishDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(adminPunishApplyQuery.getAgentId() != null, "agent_id", adminPunishApplyQuery.getAgentId());
        //如果有申请单号，则给申请单号去除空格
        if (StringUtils.isNotBlank(adminPunishApplyQuery.getApplyNo())) {
            String applyNo = StringUtils.deleteWhitespace(adminPunishApplyQuery.getApplyNo());
            queryWrapper.eq("apply_no", applyNo);
        }
        queryWrapper.eq(adminPunishApplyQuery.getIdCode() != null, "id_code", adminPunishApplyQuery.getIdCode());
        queryWrapper.eq(adminPunishApplyQuery.getDealId() != null, "deal_type_id", adminPunishApplyQuery.getDealId());
        queryWrapper.eq(adminPunishApplyQuery.getAccount() != null, "account", adminPunishApplyQuery.getAccount());
        queryWrapper.eq(adminPunishApplyQuery.getProfitType() != null, "profit_type", adminPunishApplyQuery.getProfitType());
        //状态判断
        if (adminPunishApplyQuery.getStatus() != null) {
            if (RewardPunishStatusEnum.DELETE.getStatus().equals(adminPunishApplyQuery.getStatus())) {
                queryWrapper.eq("delete_type", RewardPunishApplyDeleteStatus.CHECKING.getStatus());
            } else {
                queryWrapper.eq("delete_type", RewardPunishApplyDeleteStatus.CREAT.getStatus());
                queryWrapper.eq(adminPunishApplyQuery.getStatus() != null, "status", adminPunishApplyQuery.getStatus());
            }
        }
        queryWrapper.eq("revoke_type", RewardPunishRevokeType.NOT_REVOKE.getStatus());
        queryWrapper.ge(StringUtil.isNotBlank(adminPunishApplyQuery.getCreatedStartTime()), "created_time", adminPunishApplyQuery.getCreatedStartTime());
        queryWrapper.le(StringUtil.isNotBlank(adminPunishApplyQuery.getCreatedEndTime()), "created_time", adminPunishApplyQuery.getCreatedEndTime());
        queryWrapper.ge(StringUtil.isNotBlank(adminPunishApplyQuery.getSubmitStartTime()), "submit_time", adminPunishApplyQuery.getSubmitStartTime());
        queryWrapper.le(StringUtil.isNotBlank(adminPunishApplyQuery.getSubmitEndTime()), "submit_time", adminPunishApplyQuery.getSubmitEndTime());
        queryWrapper.ge(StringUtil.isNotBlank(adminPunishApplyQuery.getDoneStartTime()), "done_time", adminPunishApplyQuery.getDoneStartTime());
        queryWrapper.le(StringUtil.isNotBlank(adminPunishApplyQuery.getDoneEndTime()), "done_time", adminPunishApplyQuery.getDoneEndTime());
        queryWrapper.ge(StringUtil.isNotBlank(adminPunishApplyQuery.getRevokeStartTime()), "revoke_time", adminPunishApplyQuery.getRevokeStartTime());
        queryWrapper.le(StringUtil.isNotBlank(adminPunishApplyQuery.getRevokeEndTime()), "revoke_time", adminPunishApplyQuery.getRevokeEndTime());
        queryWrapper.orderByDesc("created_time");
        int pageNo = adminPunishApplyQuery.getCurrent();
        int limit = adminPunishApplyQuery.getSize();
        IPage<ServiceRewardPunishDetail> page = this.page(new Page<>(pageNo, limit), queryWrapper);
        List<AdminPunishApplyVo> resultList = new ArrayList<>();
        for (ServiceRewardPunishDetail serviceRewardPunishDetail : page.getRecords()) {
            AdminPunishApplyVo resultVo = new AdminPunishApplyVo();
            resultVo.setId(serviceRewardPunishDetail.getId());
            resultVo.setApplyNo(serviceRewardPunishDetail.getApplyNo());
            if (StringUtils.isNotBlank(serviceRewardPunishDetail.getMobile())) {
                String mobile = serviceRewardPunishDetail.getMobile().replaceAll("(\\w{3})\\w*(\\w{4})", "$1****$2");
                resultVo.setRegisterMobile(mobile);
            }
            resultVo.setName(StringUtils.isNotBlank(serviceRewardPunishDetail.getName()) ? serviceRewardPunishDetail.getName() : "");
            resultVo.setLevel(StringUtils.isNotBlank(serviceRewardPunishDetail.getLevel()) ? serviceRewardPunishDetail.getLevel() : "");
            resultVo.setRole(StringUtils.isNotBlank(serviceRewardPunishDetail.getRole()) ? serviceRewardPunishDetail.getRole() : "");
            resultVo.setMoney(serviceRewardPunishDetail.getMoney());
            resultVo.setDeductDate(serviceRewardPunishDetail.getDeductDate());
            String createdTime = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(serviceRewardPunishDetail.getCreatedTime());
            resultVo.setCreatedTime(createdTime);
            resultVo.setCreateBy(serviceRewardPunishDetail.getCreateBy());
            if (serviceRewardPunishDetail.getSubmitTime() != null) {
                String submitTime = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(serviceRewardPunishDetail.getSubmitTime());
                resultVo.setSubmitTime(submitTime);
            }
            if (serviceRewardPunishDetail.getDoneTime() != null) {
                String doneTime = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(serviceRewardPunishDetail.getDoneTime());
                resultVo.setDoneTime(doneTime);
            }
            if (serviceRewardPunishDetail.getRevokeTime() != null) {
                String revokeTime = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(serviceRewardPunishDetail.getRevokeTime());
                resultVo.setRevokeTime(revokeTime);
            }
            resultVo.setDealBy(serviceRewardPunishDetail.getDealBy());
            resultVo.setAgentId(serviceRewardPunishDetail.getAgentId());
            //获取经办人名称
            if (serviceRewardPunishDetail.getAgentId() != null) {
                ServiceRewardPunishCategory serviceRewardPunishCategory = serviceRewardPunishCategoryService.getById(serviceRewardPunishDetail.getAgentId());
                resultVo.setAgentName(serviceRewardPunishCategory.getTitle());
            }
            resultVo.setDealId(serviceRewardPunishDetail.getDealTypeId());
            //获取处理类型名称
            if (serviceRewardPunishDetail.getDealTypeId() != null) {
                ServiceRewardPunishCategory serviceRewardPunishCategory = serviceRewardPunishCategoryService.getById(serviceRewardPunishDetail.getDealTypeId());
                resultVo.setDealValue(serviceRewardPunishCategory.getTitle());
            }
            resultVo.setStatus(serviceRewardPunishDetail.getStatus());
            resultVo.setIdCode(serviceRewardPunishDetail.getIdCode());
            resultVo.setViolateValue(serviceRewardPunishDetail.getViolateValue());
            resultVo.setPlatformCode(serviceRewardPunishDetail.getPlatformCode());
            resultVo.setRemark(serviceRewardPunishDetail.getRemark());
            resultVo.setAccount(serviceRewardPunishDetail.getAccount());
            resultVo.setBeforeMoney(serviceRewardPunishDetail.getBeforeMoney());
            resultVo.setLastMoney(serviceRewardPunishDetail.getLastMoney());
            resultVo.setProfitType(serviceRewardPunishDetail.getProfitType());
            if (RewardPunishApplyDeleteStatus.CHECKING.getStatus().equals(serviceRewardPunishDetail.getDeleteType())) {
                resultVo.setStatus(RewardPunishStatusEnum.DELETE.getStatus());
            }
            resultList.add(resultVo);
        }
        IPage<AdminPunishApplyVo> pageResult = new Page<>();
        pageResult.setRecords(resultList);
        pageResult.setTotal(page.getTotal());
        return pageResult;
    }

    /**
     * 新增申请单
     *
     * @param adminPunishApplySave 请求参数
     */
    @Override
    public void insertApply(AdminPunishApplySave adminPunishApplySave) {
        //1、校验申请单号是否存在
        String applyNo = adminPunishApplySave.getApplyNo();
        QueryWrapper<ServiceRewardPunishDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("apply_no", applyNo);
        List<ServiceRewardPunishDetail> applyDetail = this.list(queryWrapper);
        if (!CollectionUtil.isEmpty(applyDetail)) {
            log.info("[财务管理后台][奖惩申请页面][新建申请单失败,该申请单号已存在,申请单号：{}]", applyNo);
            throw new ServiceException("该申请单号已存在");
        }
        //2、校验处理状态id是否存在
        ServiceRewardPunishCategory dealCategory = serviceRewardPunishCategoryService.getInfoByStatus(adminPunishApplySave.getDealId(), RewardPunishCategoryStatusEnum.ENABLE.getStatus());
        if (dealCategory == null) {
            log.info("[财务管理后台][奖惩申请页面][新建申请单失败,该处理类型不存在,申请单号：{},处理类型id:{}]", applyNo, adminPunishApplySave.getDealId());
            throw new ServiceException("新建申请单失败,该处理类型不存在或已被禁用！");
        }
        //3、校验经办人id,是否存在
        if (adminPunishApplySave.getAgentId() != null) {
            ServiceRewardPunishCategory agentCategory = serviceRewardPunishCategoryService.getInfoByStatus(adminPunishApplySave.getAgentId(), RewardPunishCategoryStatusEnum.ENABLE.getStatus());
            if (agentCategory == null) {
                log.info("[财务管理后台][奖惩申请页面][新建申请单失败,该经办人不存在,申请单号：{},经办人类型id:{}]", applyNo, adminPunishApplySave.getDealId());
                throw new ServiceException("新建申请单失败,该经办人不存在或已被禁用！");
            }
        }
        //4、校验账户是否存在
        QueryWrapper<ServiceAccount> accountQueryWrapper = new QueryWrapper<>();
        accountQueryWrapper.eq("id_code", adminPunishApplySave.getIdCode());
        CoverChargeEnum.ServiceAccountType serviceAccountType = CoverChargeEnum.ServiceAccountType.getServiceAccountTypeByPlatform(adminPunishApplySave.getPlatformCode());
        if (serviceAccountType == null) {
            log.info("[财务管理后台][奖惩申请页面][新建申请单失败,该账户不存在,申请idCode：{}]", adminPunishApplySave.getIdCode());
            throw new ServiceException("该账户不存在!");
        }
        int accountType = serviceAccountType.getCode();
        accountQueryWrapper.eq("account_type", accountType);
        ServiceAccount serviceAccount = serviceAccountService.getOne(accountQueryWrapper);
        if (serviceAccount == null) {
            log.info("[财务管理后台][奖惩申请页面][新建申请单失败,该账户不存在idCode:{},申请单号：{}]", adminPunishApplySave.getIdCode(), applyNo);
            throw new ServiceException("该账户不存在！");
        }
        //5、校验金额是否大于0
        if (adminPunishApplySave.getMoney().compareTo(new BigDecimal("0")) < 1) {
            log.info("[财务管理后台][奖惩申请页面][新建申请单失败,金额填写错误！金额:{},申请单号：{}]", adminPunishApplySave.getMoney(), applyNo);
            throw new ServiceException("金额填写错误！");
        }
        //根据idCode获取用户信息并存储
        ServiceRewardPunishDetail serviceRewardPunishDetail = new ServiceRewardPunishDetail();
        try {
            UserInfo userInfo = userDocService.searchUserByIdCodeOrMobile(new UserIdCode(adminPunishApplySave.getIdCode()),null);
            if (userInfo == null) {
                log.info("[财务管理后台][奖惩申请页面][用户手机号查询失败,用户idCod:{}]", serviceRewardPunishDetail.getIdCode());
                throw new ServiceException("用户信息获取失败,请确认idCode是否填写正确!");
            }
            serviceRewardPunishDetail.setMobile(userInfo.getMobile());
            serviceRewardPunishDetail.setName(userInfo.getName());
//            Result<ProviderExt> result = brandProviderLevelServer.getByIdCodeAndType(adminPunishApplySave.getIdCode(), SourceTypeEnum.getSourceCode(adminPunishApplySave.getPlatformCode()));
//            if (result == null || result.getData() == null) {
//                log.info("[财务管理后台][奖惩申请页面][用户等级查询失败,用户idCod:{}]", serviceRewardPunishDetail.getIdCode());
//                throw new ServiceException("用户信息获取失败,请确认idCode是否填写正确!");
//            }
//            serviceRewardPunishDetail.setLevel(UserLevelEnum.getMsg(result.getData().getBrandProviderLevel()));
//            JsonResult<RoleDTO> memberResult = roleFeign.getByIdCode(Long.parseLong(adminPunishApplySave.getIdCode().toString()));
//            if (memberResult == null || memberResult.getData() == null) {
//                log.info("[财务管理后台][奖惩申请页面][用户角色查询失败,用户idCod:{}]", serviceRewardPunishDetail.getIdCode());
//                throw new ServiceException("用户信息获取失败,请确认idCode是否填写正确!");
//            }
//            serviceRewardPunishDetail.setRole(RoleEnum.fromCode(memberResult.getData().getRoleEnum()).getDesc());
        } catch (Exception e) {
            log.error("[财务管理后台][奖惩申请页面][用户信息查询失败,用户idCod:{}]", serviceRewardPunishDetail.getIdCode(), e);
            throw new ServiceException("提交失败！未查询到该用户信息,请确认idCode是否填写正确!");
        }
        serviceRewardPunishDetail.setApplyNo(adminPunishApplySave.getApplyNo());
        serviceRewardPunishDetail.setIdCode(adminPunishApplySave.getIdCode());
        serviceRewardPunishDetail.setAccount("服务费账户");
        serviceRewardPunishDetail.setDealTypeId(adminPunishApplySave.getDealId());
        serviceRewardPunishDetail.setViolateValue(StringUtils.isBlank(adminPunishApplySave.getViolateValue()) ? "" : adminPunishApplySave.getViolateValue());
        serviceRewardPunishDetail.setMoney(adminPunishApplySave.getMoney());
        //校验扣除日期是否符合YYYY-MM格式
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        try {
            format.parse(adminPunishApplySave.getDeductDate());
        } catch (Exception e) {
            log.info("[财务管理后台][奖惩申请页面][新建申请失败,扣除期间填写错误,值为:{}]", adminPunishApplySave.getDeductDate());
            throw new ServiceException("扣除期间填写不正确！");
        }
        serviceRewardPunishDetail.setDeductDate(adminPunishApplySave.getDeductDate());
        serviceRewardPunishDetail.setPlatformCode(adminPunishApplySave.getPlatformCode());
        serviceRewardPunishDetail.setProfitType(adminPunishApplySave.getProfitType());
        if (adminPunishApplySave.getAgentId() != null) {
            serviceRewardPunishDetail.setAgentId(adminPunishApplySave.getAgentId());
        }
        if (StringUtils.isNotBlank(adminPunishApplySave.getRemark())) {
            serviceRewardPunishDetail.setRemark(adminPunishApplySave.getRemark());
        }
        serviceRewardPunishDetail.setCreatedTime(LocalDateTime.now());
        serviceRewardPunishDetail.setCreateBy(adminPunishApplySave.getOperate());
        this.save(serviceRewardPunishDetail);
    }

    /**
     * 获取申请单审核搜索条件
     *
     * @param adminPunishDealQuery 请求参数
     * @return 返回结果
     */
    private QueryWrapper<ServiceRewardPunishDetail> getQueryWhere(AdminPunishDealQuery adminPunishDealQuery) {
        QueryWrapper<ServiceRewardPunishDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(adminPunishDealQuery.getAgentId() != null, "agent_id", adminPunishDealQuery.getAgentId());
        queryWrapper.eq(StringUtils.isNotBlank(adminPunishDealQuery.getApplyNo()), "apply_no", adminPunishDealQuery.getApplyNo());
        queryWrapper.eq(adminPunishDealQuery.getIdCode() != null, "id_code", adminPunishDealQuery.getIdCode());
        queryWrapper.eq(StringUtils.isNotBlank(adminPunishDealQuery.getAccount()), "account", adminPunishDealQuery.getAccount());
        queryWrapper.eq(adminPunishDealQuery.getDealId() != null, "deal_type_id", adminPunishDealQuery.getDealId());
        queryWrapper.eq(adminPunishDealQuery.getProfitType() != null, "profit_type", adminPunishDealQuery.getProfitType());
        queryWrapper.eq("revoke_type", RewardPunishRevokeTypeEnum.REVOKE_NO.getStatus());
        //状态判断
        if (adminPunishDealQuery.getStatus() != null) {
            if (RewardPunishStatusEnum.DELETE.getStatus().equals(adminPunishDealQuery.getStatus())) {
                queryWrapper.eq("delete_type", RewardPunishApplyDeleteStatus.CHECKING.getStatus());
            } else {
                queryWrapper.eq("status", adminPunishDealQuery.getStatus());
                queryWrapper.eq("delete_type", RewardPunishApplyDeleteStatus.CREAT.getStatus());
            }
        } else {
            queryWrapper.in("status", RewardPunishStatusEnum.CHECKING.getStatus(), RewardPunishStatusEnum.PASS.getStatus(), RewardPunishStatusEnum.REVOKE.getStatus());
            queryWrapper.eq("delete_type", RewardPunishApplyDeleteStatus.CREAT.getStatus());
        }
        if (StringUtils.isNotBlank(adminPunishDealQuery.getDoneStartTime()) && StringUtils.isNotBlank(adminPunishDealQuery.getDoneEndTime())) {
            queryWrapper.ge("submit_time", adminPunishDealQuery.getDoneStartTime());
            queryWrapper.le("submit_time", adminPunishDealQuery.getDoneEndTime());
        }
        return queryWrapper;
    }

    /**
     * 获取申请单审核总数
     *
     * @param adminPunishDealQuery 请求参数
     * @return 返回结果
     */
    @Override
    public Integer getApplyCheckTotal(AdminPunishDealQuery adminPunishDealQuery) {
        QueryWrapper<ServiceRewardPunishDetail> queryWrapper = getQueryWhere(adminPunishDealQuery);
        return this.baseMapper.selectCount(queryWrapper);
    }

    /**
     * 获取申请单信息
     *
     * @param adminPunishDealQuery 请求参数
     * @return 返回结果
     */
    @Override
    public IPage<AdminPunishDealVo> getApplyCheckList(AdminPunishDealQuery adminPunishDealQuery) {
        //1、根据参数查询
        QueryWrapper<ServiceRewardPunishDetail> queryWrapper = getQueryWhere(adminPunishDealQuery);
        queryWrapper.orderByDesc("id");
        int pageNo = adminPunishDealQuery.getCurrent();
        int limit = adminPunishDealQuery.getSize();
        IPage<ServiceRewardPunishDetail> page = this.page(new Page<>(pageNo, limit), queryWrapper);
        List<AdminPunishDealVo> resultList = new ArrayList<>();
        for (ServiceRewardPunishDetail serviceRewardPunishDetail : page.getRecords()) {
            AdminPunishDealVo resultVo = new AdminPunishDealVo();
            if (StringUtils.isNotBlank(serviceRewardPunishDetail.getMobile())) {
                serviceRewardPunishDetail.setMobile(serviceRewardPunishDetail.getMobile().replaceAll("(\\w{3})\\w*(\\w{4})", "$1****$2"));
            }
            resultVo.setRegisterMobile(serviceRewardPunishDetail.getMobile());
            resultVo.setName(serviceRewardPunishDetail.getName());
            resultVo.setLevel(serviceRewardPunishDetail.getLevel());
            resultVo.setRole(serviceRewardPunishDetail.getRole());
            //获取经办人名称
            if (serviceRewardPunishDetail.getAgentId() != null) {
                QueryWrapper<ServiceRewardPunishCategory> categoryQueryWrapper = new QueryWrapper<>();
                categoryQueryWrapper.eq("id", serviceRewardPunishDetail.getAgentId());
                ServiceRewardPunishCategory serviceRewardPunishCategory = serviceRewardPunishCategoryService.getOne(categoryQueryWrapper);
                resultVo.setAgentName(serviceRewardPunishCategory.getTitle());
            }
            resultVo.setDealId(serviceRewardPunishDetail.getDealTypeId());
            //获取处理类型名称
            if (serviceRewardPunishDetail.getDealTypeId() != null) {
                QueryWrapper<ServiceRewardPunishCategory> categoryQueryWrapper = new QueryWrapper<>();
                categoryQueryWrapper.eq("id", serviceRewardPunishDetail.getDealTypeId());
                ServiceRewardPunishCategory serviceRewardPunishCategory = serviceRewardPunishCategoryService.getOne(categoryQueryWrapper);
                resultVo.setDealValue(serviceRewardPunishCategory.getTitle());
            }
            resultVo.setId(serviceRewardPunishDetail.getId());
            resultVo.setApplyNo(serviceRewardPunishDetail.getApplyNo());
            resultVo.setCreateBy(serviceRewardPunishDetail.getCreateBy());
            if (serviceRewardPunishDetail.getSubmitTime() != null) {
                String submitTime = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(serviceRewardPunishDetail.getSubmitTime());
                resultVo.setSubmitTime(submitTime);
            }
            resultVo.setDealBy(serviceRewardPunishDetail.getDealBy());
            resultVo.setAgentId(serviceRewardPunishDetail.getAgentId());
            resultVo.setStatus(serviceRewardPunishDetail.getStatus());
            resultVo.setIdCode(serviceRewardPunishDetail.getIdCode());
            resultVo.setViolateValue(serviceRewardPunishDetail.getViolateValue());
            resultVo.setPlatformCode(serviceRewardPunishDetail.getPlatformCode());
            resultVo.setRemark(serviceRewardPunishDetail.getRemark());
            resultVo.setAccount(serviceRewardPunishDetail.getAccount());
            resultVo.setBeforeMoney(serviceRewardPunishDetail.getBeforeMoney());
            resultVo.setLastMoney(serviceRewardPunishDetail.getLastMoney());
            resultVo.setProfitType(serviceRewardPunishDetail.getProfitType());
            if (RewardPunishApplyDeleteStatus.CHECKING.getStatus().equals(serviceRewardPunishDetail.getDeleteType())) {
                resultVo.setStatus(RewardPunishStatusEnum.DELETE.getStatus());
            }
            resultVo.setMoney(serviceRewardPunishDetail.getMoney());
            resultVo.setDeductDate(serviceRewardPunishDetail.getDeductDate());
            String createdTime = DateTimeFormatter.ofPattern(DateTimeUtils.DEFAULT_DATE_TIME_FORMAT).format(serviceRewardPunishDetail.getCreatedTime());
            resultVo.setCreatedTime(createdTime);
            if (serviceRewardPunishDetail.getDoneTime() != null) {
                String doneTime = DateTimeFormatter.ofPattern(DateTimeUtils.DEFAULT_DATE_TIME_FORMAT).format(serviceRewardPunishDetail.getDoneTime());
                resultVo.setDoneTime(doneTime);
            }

            if (serviceRewardPunishDetail.getRevokeTime() != null) {
                String revokeTime = DateTimeFormatter.ofPattern(DateTimeUtils.DEFAULT_DATE_TIME_FORMAT).format(serviceRewardPunishDetail.getRevokeTime());
                resultVo.setRevokeTime(revokeTime);
            }
            resultVo.setStatusStr(RewardPunishStatusEnum.getStatusDesc(serviceRewardPunishDetail.getStatus()).getMsg());
            resultList.add(resultVo);
        }
        IPage<AdminPunishDealVo> pageResult = new Page<>();
        pageResult.setRecords(resultList);
        pageResult.setTotal(page.getTotal());
        return pageResult;

    }

    /**
     * 根据申请编号单获取信息
     *
     * @param applyNo 申请编号
     * @return 返回结果
     */
    @Override
    public List<ServiceRewardPunishDetail> getApplyList(String applyNo) {
        QueryWrapper<ServiceRewardPunishDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("apply_no", applyNo);
        return this.baseMapper.selectList(queryWrapper);
    }

    /**
     * 根据申请编号单获取总数
     *
     * @param applyNoList 申请编号
     * @return 返回结果
     */
    @Override
    public Integer sumApplyNum(List<String> applyNoList) {
        QueryWrapper<ServiceRewardPunishDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("apply_no", applyNoList);
        return this.baseMapper.selectCount(queryWrapper);
    }

    /**
     * 剔除重复元素
     *
     * @param list
     * @return 返回结果
     */
    @Override
    public List<String> removeDuplicate(List<String> list) {
        HashSet h = new HashSet(list);
        list.clear();
        list.addAll(h);
        return list;
    }

    /**
     * redis设置和判断
     *
     * @param id      申请记录id
     * @param applyNo 运单号
     * @return 返回结果
     */
    @Override
    public RewardPunishRedisReturnVo redisSet(Long id, String applyNo) {
        RewardPunishRedisReturnVo rewardPunishRedisReturnVo = new RewardPunishRedisReturnVo();
        rewardPunishRedisReturnVo.setIsSet(Boolean.FALSE);

        String flag = applyNo + "-" + id;

        //1、获取key
        String lockKey = BizConstants.REWARD_PUNISH_APPLY_APPROVED_AGING_ + flag;
        String checkApply = RedisUtil.getInstance().get(lockKey);
        if (!StringUtils.isEmpty(checkApply)) {
            rewardPunishRedisReturnVo.setMsg("请勿重复操作");
            return rewardPunishRedisReturnVo;
        }

        //2、存入key,15秒钟
        if (!RedisUtil.getInstance().setIfAbsent(lockKey, flag, 15, TimeUnit.SECONDS)) {
            rewardPunishRedisReturnVo.setMsg("操作失败,设置缓存出错");
            return rewardPunishRedisReturnVo;
        }

        rewardPunishRedisReturnVo.setIsSet(Boolean.TRUE);
        return rewardPunishRedisReturnVo;
    }

    /**
     * 更新任务
     *
     * @param taskNo 任务编号
     * @param status 状态
     * @param msg    描述
     * @return 返回结果
     */
    @Override
    public Boolean updateTask(String taskNo, Integer status, String msg) {
        //查询键
        QueryWrapper<ServiceTask> queryTaskWrapper = new QueryWrapper<>();
        queryTaskWrapper.eq("task_no", taskNo);
        ServiceTask serviceTask = taskService.getOne(queryTaskWrapper);
        if (Objects.isNull(serviceTask)) {
            log.warn("[违约金][批量处理][任务编号不存在],taskNo{}", taskNo);
            return Boolean.FALSE;
        }

        updateTaskDb(serviceTask, status, msg);
        return Boolean.TRUE;
    }

    /**
     * 获取页码
     *
     * @param count 总数
     * @return 返回结果
     */
    @Override
    public Integer getPage(Long count) {
        return Math.toIntExact((count / PageSize.REWARD_EXPORT_PAGE_SIZE + (count % PageSize.REWARD_EXPORT_PAGE_SIZE > 0 ? 1 : 0)));
    }

    /**
     * 更新任务
     *
     * @param serviceTask 任务编号
     * @param status      状态
     * @param msg         状态描述
     * @return 返回结果
     */
    private void updateTaskDb(ServiceTask serviceTask, Integer status, String msg) {
        if (Objects.nonNull(serviceTask)) {
            //任务更新
            ServiceTask updateTask = new ServiceTask();
            updateTask.setId(serviceTask.getId());
            updateTask.setUpdateTime(DateTimeUtils.dateToLocalDateTime(new Date()));

            //处理中
            if (TaskStatusEnum.DEAL.getCode().equals(status)) {
                updateTask.setDealSize(serviceTask.getDealSize() + 1);
            } else if (TaskStatusEnum.FAIL.getCode().equals(status)) {//失败
                int deal = serviceTask.getDealSize() - 1;
                if (deal <= 0) {
                    deal = 0;
                }
                String errorMsg = serviceTask.getTaskErrorMsg();
                if (StringUtils.isBlank(errorMsg)) {
                    updateTask.setTaskErrorMsg(msg);
                } else {
                    updateTask.setTaskErrorMsg(errorMsg + "," + msg);
                }
                updateTask.setDealSize(deal);
                updateTask.setFailSize(serviceTask.getFailSize() + 1);
                updateTask.setTaskStatus(TaskStatusEnum.FAIL.getCode());
            } else {//成功
                int deal = serviceTask.getDealSize() - 1;
                if (deal <= 0) {
                    deal = 0;
                }
                updateTask.setDealSize(deal);
                updateTask.setSuccessSize(serviceTask.getSuccessSize() + 1);
                if (updateTask.getSuccessSize().equals(serviceTask.getTaskSize())) {
                    updateTask.setTaskStatus(TaskStatusEnum.SUCCESS.getCode());
                }
            }
            taskService.updateById(updateTask);
        }
    }

    /**
     * 审核通过
     *
     * @param taskNo 申请任务
     * @param id     申请记录id
     * @param dealBy 审核人
     * @return 返回结果
     */
    @Override
    public Boolean approved(String taskNo, Long id, String dealBy) {
        //获取当前时间
        Date date = new Date();
        LocalDateTime nowTime = DateTimeUtils.dateToLocalDateTime(date);

        //查询键
        QueryWrapper<ServiceTask> queryTaskWrapper = new QueryWrapper<>();
        queryTaskWrapper.eq("task_no", taskNo);
        ServiceTask serviceTask = taskService.getOne(queryTaskWrapper);
        if (Objects.isNull(serviceTask)) {
            log.warn("[违约金][审核通过][任务编号不存在],taskNo{}", taskNo);
            return Boolean.FALSE;
        }

        //1、获取申请单信息
        ServiceRewardPunishDetail serviceRewardPunishDetail = this.baseMapper.selectById(id);
        if (Objects.isNull(serviceRewardPunishDetail)) {
            log.warn("[违约金][审核通过][记录不存在],id{}", id);
            updateTaskDb(serviceTask, TaskStatusEnum.FAIL.getCode(), id + "申请记录不存在");
            return Boolean.FALSE;
        }
        //2、判断状态
        if (!serviceRewardPunishDetail.getStatus().equals(RewardPunishStatusEnum.CHECKING.getStatus())) {
            log.warn("[违约金][审核通过][状态不对]status{}", serviceRewardPunishDetail.getStatus());
            updateTaskDb(serviceTask, TaskStatusEnum.FAIL.getCode(), id + "申请记录状态不对(" + serviceRewardPunishDetail.getStatus() + ")");
            return Boolean.FALSE;
        }
        //3、判断服务费账户存不存在
        QueryWrapper<ServiceAccount> queryAccountWrapper = new QueryWrapper<>();
        queryAccountWrapper.eq("id_code", serviceRewardPunishDetail.getIdCode());
        //queryAccountWrapper.eq("account_type", CoverChargeEnum.ServiceAccountType.CUSTOMER_TYPE.getCode());
        ServiceAccount serviceAccount = serviceAccountService.getOne(queryAccountWrapper);
        if (Objects.isNull(serviceAccount)) {
            log.warn("[违约金][审核通过][账户不存在]id{},idCode{}", id, serviceRewardPunishDetail.getIdCode());

            //更新处理失败数量
            updateTaskDb(serviceTask, TaskStatusEnum.FAIL.getCode(), id + "申请记录账户不存在");
            return Boolean.FALSE;
        }

        //4.数据库核心操作
        approvedDb(serviceAccount, serviceRewardPunishDetail, serviceTask, nowTime, id, dealBy);

        try {
            //5、发送站短信
            String messageContent = "尊敬的用户，您好。根据此前通知记录，本次已对您违规记录对应的违约金金额："+serviceRewardPunishDetail.getMoney()+"元进行了相应扣除，请知悉。";
            userMessageClient.rewardSendMobileMessageByTemplate(serviceRewardPunishDetail.getIdCode(), MessageTemplateIdEnum.ABM.getCode(), messageContent);

            //发送站内信
            userMessageClient.sendDtServiceFeeMessage(serviceRewardPunishDetail.getIdCode(), "违约金处理提示", messageContent, true, true, false);
        } catch (Exception e) {
            log.warn("[违约金][审核通过][发送短信失败]id{},idCode{},info{}", id, serviceRewardPunishDetail.getIdCode(), e);
        }

        return Boolean.TRUE;
    }

    /**
     * 审核通过数据库核心操作
     *
     * @param serviceAccount            账户信息
     * @param serviceRewardPunishDetail 申请单
     * @param nowTime                   时间
     * @param id                        记录id
     * @param dealBy                    审核人
     * @return null
     */
    @Transactional(rollbackFor = Exception.class)
    public void approvedDb(ServiceAccount serviceAccount, ServiceRewardPunishDetail serviceRewardPunishDetail, ServiceTask serviceTask, LocalDateTime nowTime, Long id, String dealBy) {
        try {
            //1、更新申请单数据准备
            ServiceRewardPunishDetail rewardPunishDetail = new ServiceRewardPunishDetail();
            rewardPunishDetail.setId(id);
            rewardPunishDetail.setDoneTime(nowTime);
            rewardPunishDetail.setStatus(RewardPunishStatusEnum.PASS.getStatus());
            rewardPunishDetail.setBeforeMoney(serviceAccount.getBalance());
            rewardPunishDetail.setUpdateBy(dealBy);
            rewardPunishDetail.setDealBy(dealBy);

            //2、操作后金额，欠费金额，服务费账户金额
            BigDecimal lastMoney, amount, accountMoney;

            //3、服务费账户余额小于等于0
            if (serviceAccount.getBalance().compareTo(BigDecimal.ZERO) <= 0) {
                lastMoney = BigDecimal.ZERO;
                rewardPunishDetail.setLastMoney(lastMoney);
                //更新申请单
                this.updateById(rewardPunishDetail);

                //插入欠费金额表
                amount = serviceRewardPunishDetail.getMoney();
                saveArrearDetail(serviceRewardPunishDetail.getIdCode(), id, nowTime, amount);

                //更新处理成功
                updateTaskDb(serviceTask, TaskStatusEnum.SUCCESS.getCode(), null);
                return;
            }

            //4.服务费账户余额大于或者等于申请单金额
            if (serviceAccount.getBalance().compareTo(serviceRewardPunishDetail.getMoney()) >= 0) {
                accountMoney = serviceAccount.getBalance().subtract(serviceRewardPunishDetail.getMoney());
                amount = serviceRewardPunishDetail.getMoney();
            } else {
                //5、服务费账户余额小于申请单金额
                accountMoney = BigDecimal.ZERO;
                //申请金额减去账户余额
                amount = serviceAccount.getBalance();
                //插入欠费金额表
                saveArrearDetail(serviceRewardPunishDetail.getIdCode(), id, nowTime, serviceRewardPunishDetail.getMoney().subtract(serviceAccount.getBalance()));
            }

            //6、更新账户金额
            updateAccount(serviceAccount, accountMoney);

            //7、插入流水表
            savecustomDetail(serviceAccount, accountMoney, serviceRewardPunishDetail.getIdCode(), amount, nowTime, serviceRewardPunishDetail.getId().intValue(), "违约金扣除", ProfitTypeEnum.rewards_pt_out.getCode());

            //8、更新申请表
            rewardPunishDetail.setLastMoney(accountMoney);
            //更新申请单
            this.updateById(rewardPunishDetail);

            //9、更新任务处理成功数量
            updateTaskDb(serviceTask, TaskStatusEnum.SUCCESS.getCode(), null);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
    }

    /**
     * 插入欠费表
     *
     * @param idCode  代理id
     * @param id      申请记录id
     * @param nowTime 当前时间
     * @param amount  金额
     * @return null
     */
    private void saveArrearDetail(Integer idCode, Long id, LocalDateTime nowTime, BigDecimal amount) {
        ServiceArrearDetail serviceArrearDetail = new ServiceArrearDetail();
        serviceArrearDetail.setIdCode(idCode);
        serviceArrearDetail.setProfitType(ProfitTypeEnum.rewards_pt_out.getCode());
        serviceArrearDetail.setRemark("违约金扣除");
        serviceArrearDetail.setTableId(id);
        serviceArrearDetail.setAmount(amount);
        serviceArrearDetail.setStatus(ArrearDetailStatusEnum.NOT_DEAL.getStatus());
        serviceArrearDetail.setCreatedTime(nowTime);
        serviceArrearDetail.setUpdtaeTime(nowTime);
        serviceArrearDetailService.save(serviceArrearDetail);
    }

    /**
     * 更新账户表
     *
     * @param serviceAccount 账户信息
     * @param accountMoney   更新金额
     * @return null
     */
    private void updateAccount(ServiceAccount serviceAccount, BigDecimal accountMoney) {
        Integer version = serviceAccount.getVersion();

        //更新数据
        ServiceAccount serviceAccountUp = new ServiceAccount();
        serviceAccountUp.setVersion(version + 1);
        serviceAccountUp.setBalance(accountMoney);

        //更新条件
        ServiceAccount serviceAccountWhere = new ServiceAccount();
        serviceAccountWhere.setId(serviceAccount.getId());
        serviceAccountWhere.setVersion(version);

        boolean result = serviceAccountService.update(serviceAccountUp, new UpdateWrapper<>(serviceAccountWhere));
        if (!result) {
            log.error("[违约金][审核通过][服务费账户数据处理失败]account：{}", serviceAccount);
            throw new ServiceException("服务费账户数据处理失败");
        }
    }

    /**
     * 插入流水表
     *
     * @param serviceAccount 账户信息
     * @param accountMoney   更新金额
     * @param idCode         代理id
     * @param money          操作金额
     * @param nowTime        当前时间
     * @param tableId        当前操作表id
     * @param des            备注
     * @param profitType     操作类型
     * @return null
     */
    private void savecustomDetail(ServiceAccount serviceAccount, BigDecimal accountMoney, Integer idCode, BigDecimal money, LocalDateTime nowTime, Integer tableId, String des, Integer profitType) {
        ServiceCustomDetail customDetail = new ServiceCustomDetail();
        //处理成功，插入流水表
        customDetail.setIdCode(idCode);
        customDetail.setDes(des);
        customDetail.setAmount(money);
        customDetail.setBalance(accountMoney);
        customDetail.setFreezeBalance(serviceAccount.getFreezeBalance());
        customDetail.setProfitType(profitType);
        customDetail.setCreatedAt(nowTime);
        customDetail.setUpdatedAt(nowTime);
        customDetail.setTableId(tableId);
        boolean resultCustom = serviceCustomDetailService.save(customDetail);
        if (!resultCustom) {
            log.error("[违约金][审核通过][客户收益账户数据处理失败]，customDetail：{}", customDetail);
            throw new ServiceException("客户收益账户数据处理失败");
        }
    }

    /**
     * 驳回
     *
     * @param id     申请记录id
     * @param dealBy 审核人
     * @param taskNo 驳回单号
     * @return 返回结果
     */
    @Override
    public Boolean rejectApply(Long id, String dealBy, String taskNo) {
        //批量操作
        ServiceTask serviceTask = new ServiceTask();
        if (StringUtils.isNotBlank(taskNo)) {
            //查询键
            QueryWrapper<ServiceTask> queryTaskWrapper = new QueryWrapper<>();
            queryTaskWrapper.eq("task_no", taskNo);
            serviceTask = taskService.getOne(queryTaskWrapper);
            if (Objects.isNull(serviceTask)) {
                log.warn("[违约金][批量驳回][任务编号不存在],taskNo{}", taskNo);
                return Boolean.FALSE;
            }
        }

        //1、获取申请单信息
        ServiceRewardPunishDetail serviceRewardPunishDetail = this.baseMapper.selectById(id);
        if (Objects.isNull(serviceRewardPunishDetail)) {
            log.warn("[违约金][驳回][记录不存在],id{}", id);

            //批量操作
            if (serviceTask.getId() != null && StringUtils.isNotBlank(taskNo)) {
                updateTaskDb(serviceTask, TaskStatusEnum.FAIL.getCode(), id + "申请记录不存在");
            }
            return Boolean.FALSE;
        }
        //2、判断状态
        if (!serviceRewardPunishDetail.getStatus().equals(RewardPunishStatusEnum.CHECKING.getStatus())) {
            log.warn("[违约金][驳回][状态不对]status{}", serviceRewardPunishDetail.getStatus());
            //批量操作
            if (serviceTask.getId() != null && StringUtils.isNotBlank(taskNo)) {
                updateTaskDb(serviceTask, TaskStatusEnum.FAIL.getCode(), id + "申请记录状态不对(" + serviceRewardPunishDetail.getStatus() + ")");
            }
            return Boolean.FALSE;
        }

        //4、更新申请单数据准备
        ServiceRewardPunishDetail rewardPunishDetail = new ServiceRewardPunishDetail();
        rewardPunishDetail.setId(serviceRewardPunishDetail.getId());
        rewardPunishDetail.setStatus(RewardPunishStatusEnum.REJECT.getStatus());
        rewardPunishDetail.setUpdateBy(dealBy);
        rewardPunishDetail.setDealBy(dealBy);
        this.updateById(rewardPunishDetail);

        //批量操作
        if (serviceTask.getId() != null && StringUtils.isNotBlank(taskNo)) {
            updateTaskDb(serviceTask, TaskStatusEnum.SUCCESS.getCode(), null);
        }
        return Boolean.TRUE;
    }

    /**
     * 撤销
     *
     * @param id     申请记录id
     * @param dealBy 审核人
     * @param taskNo 申请任务
     * @return 返回结果
     */
    @Override
    public Boolean revokeApply(Long id, String dealBy, String applyNo, String taskNo) {
        //批量操作
        ServiceTask serviceTask = new ServiceTask();
        if (StringUtils.isNotBlank(taskNo)) {
            //查询键
            QueryWrapper<ServiceTask> queryTaskWrapper = new QueryWrapper<>();
            queryTaskWrapper.eq("task_no", taskNo);
            serviceTask = taskService.getOne(queryTaskWrapper);
            if (Objects.isNull(serviceTask)) {
                log.warn("[违约金][批量驳回][任务编号不存在],taskNo{}", taskNo);
                return Boolean.FALSE;
            }
        }

        //1、获取申请单信息
        ServiceRewardPunishDetail serviceRewardPunishDetail = this.baseMapper.selectById(id);
        if (Objects.isNull(serviceRewardPunishDetail)) {
            log.warn("[违约金][撤销][记录不存在],id{}", id);
            //批量操作
            if (serviceTask.getId() != null && StringUtils.isNotBlank(taskNo)) {
                updateTaskDb(serviceTask, TaskStatusEnum.FAIL.getCode(), id + "申请记录不存在");
            }
            return Boolean.FALSE;
        }

        if (!serviceRewardPunishDetail.getApplyNo().equals(applyNo)) {
            log.warn("[违约金][撤销][记录与传入申请单号不对],id{},applyNo{}", id, applyNo);
            //批量操作
            if (serviceTask.getId() != null && StringUtils.isNotBlank(taskNo)) {
                updateTaskDb(serviceTask, TaskStatusEnum.FAIL.getCode(), id + "记录与传入申请单号不对" + applyNo);
            }
            return Boolean.FALSE;
        }

        //2、判断状态
        if (!serviceRewardPunishDetail.getStatus().equals(RewardPunishStatusEnum.PASS.getStatus())) {
            log.warn("[违约金][撤销][状态不对]status{}", serviceRewardPunishDetail.getStatus());
            //批量操作
            if (serviceTask.getId() != null && StringUtils.isNotBlank(taskNo)) {
                updateTaskDb(serviceTask, TaskStatusEnum.FAIL.getCode(), id + "申请记录状态不对(" + serviceRewardPunishDetail.getStatus() + ")");
            }
            return Boolean.FALSE;
        }
        //3、判断服务费账户存不存在
        QueryWrapper<ServiceAccount> queryAccountWrapper = new QueryWrapper<>();
        queryAccountWrapper.eq("id_code", serviceRewardPunishDetail.getIdCode());
        //queryAccountWrapper.eq("account_type", CoverChargeEnum.ServiceAccountType.CUSTOMER_TYPE.getCode());
        ServiceAccount serviceAccount = serviceAccountService.getOne(queryAccountWrapper);
        if (Objects.isNull(serviceAccount)) {
            log.warn("[违约金][撤销][账户不存在]id{},idCode{}", id, serviceRewardPunishDetail.getIdCode());
            //批量操作
            if (serviceTask.getId() != null && StringUtils.isNotBlank(taskNo)) {
                updateTaskDb(serviceTask, TaskStatusEnum.FAIL.getCode(), id + "账户不存在");
            }
            return Boolean.FALSE;
        }

        Date date = new Date();
        LocalDateTime nowTime = DateTimeUtils.dateToLocalDateTime(date);

        //生成随机单号
        String applyNoNew = creatApplyNo();
        //4、数据库核心操作
        revokeApplyDb(serviceAccount, serviceRewardPunishDetail, serviceTask, nowTime, id, dealBy, taskNo, applyNoNew);

        try {
            //5、发送站短信
            String messageContent = "尊敬的用户，您好。您的异议已审核通过，已将相关款项金额："+serviceRewardPunishDetail.getMoney()+"元返还至您的账户，请您核对。";
            userMessageClient.rewardSendMobileMessageByTemplate(serviceRewardPunishDetail.getIdCode(), MessageTemplateIdEnum.ABM.getCode(), messageContent);

            //发送站内信
            userMessageClient.sendDtServiceFeeMessage(serviceRewardPunishDetail.getIdCode(), "违约金处理提示", messageContent, true, true, false);
        } catch (Exception e) {
            log.warn("违约金][撤销][发送短信失败]id{},idCode{},info{}", id, serviceRewardPunishDetail.getIdCode(), e);
        }

        return Boolean.TRUE;
    }

    /**
     * 撤销数据库操作
     *
     * @param serviceAccount            账户信息
     * @param serviceRewardPunishDetail 申请单
     * @param nowTime                   时间
     * @param id                        记录id
     * @param dealBy                    审核人
     * @param taskNo                    任务单
     * @return null
     */
    @Transactional(rollbackFor = Exception.class)
    public void revokeApplyDb(ServiceAccount serviceAccount, ServiceRewardPunishDetail serviceRewardPunishDetail, ServiceTask serviceTask, LocalDateTime nowTime, Long id, String dealBy, String taskNo, String applyNoNew) {
        try {
            //1、操作后账户金额
            BigDecimal accountMoney;

            //原账户金额大于或者等于扣费金额，当前账户余额+申请金额
            if (serviceRewardPunishDetail.getBeforeMoney().compareTo(serviceRewardPunishDetail.getMoney()) >= 0) {
                accountMoney = serviceAccount.getBalance().add(serviceRewardPunishDetail.getMoney());
            } else {
                //原账户金额小于扣费金额，当前账户余额+申请金额时的账户金额
                accountMoney = serviceAccount.getBalance().add(serviceRewardPunishDetail.getBeforeMoney());
            }

            //2.更新欠费表，更新条件
            QueryWrapper<ServiceArrearDetail> queryArrearWrapper = new QueryWrapper<>();
            queryArrearWrapper.eq("id_code", serviceRewardPunishDetail.getIdCode());
            queryArrearWrapper.eq("profit_type", ProfitTypeEnum.rewards_pt_out.getCode());
            queryArrearWrapper.eq("table_id", id);
            queryArrearWrapper.eq("status", ArrearDetailStatusEnum.NOT_DEAL.getStatus());
            //更新数据
            ServiceArrearDetail serviceArrearDetailUpdate = new ServiceArrearDetail();
            serviceArrearDetailUpdate.setStatus(ArrearDetailStatusEnum.DEAL.getStatus());
            serviceArrearDetailUpdate.setUpdtaeTime(nowTime);
            serviceArrearDetailService.update(serviceArrearDetailUpdate, queryArrearWrapper);

            //3、更新账户金额
            updateAccount(serviceAccount, accountMoney);

            //4、插入流水表
            savecustomDetail(serviceAccount, accountMoney, serviceRewardPunishDetail.getIdCode(), serviceRewardPunishDetail.getMoney(), nowTime, serviceRewardPunishDetail.getId().intValue(), "违约金撤销", ProfitTypeEnum.rewards_pt_in.getCode());

            //5、更新原纪录
            ServiceRewardPunishDetail oldRewardPunishDetail = new ServiceRewardPunishDetail();
            oldRewardPunishDetail.setId(serviceRewardPunishDetail.getId());
            oldRewardPunishDetail.setRevokeTime(nowTime);
            oldRewardPunishDetail.setStatus(RewardPunishStatusEnum.REVOKE.getStatus());
            oldRewardPunishDetail.setUpdateBy(dealBy);
            oldRewardPunishDetail.setDealBy(dealBy);
            this.updateById(oldRewardPunishDetail);

            //setLastMoney(accountMoney),setBeforeMoney(serviceAccount.getBalance())

            //6、插入新的申请单
            insertNewRewardPunishDetail(serviceRewardPunishDetail, nowTime, dealBy, serviceAccount.getBalance(), accountMoney, applyNoNew);

            //7、批量操作
            if (serviceTask.getId() != null && StringUtils.isNotBlank(taskNo)) {
                updateTaskDb(serviceTask, TaskStatusEnum.SUCCESS.getCode(), null);
            }
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
    }

    /**
     * 插入新的申请单
     * serviceRewardPunishDetail
     */
    private void insertNewRewardPunishDetail(ServiceRewardPunishDetail serviceRewardPunishDetail, LocalDateTime nowTime, String updateBy, BigDecimal beforeMoney, BigDecimal lastMoney, String applyNoNew) {
        ServiceRewardPunishDetail newRewardPunishDetail = new ServiceRewardPunishDetail();
        newRewardPunishDetail.setIdCode(serviceRewardPunishDetail.getIdCode());
        newRewardPunishDetail.setMobile(serviceRewardPunishDetail.getMobile());
        newRewardPunishDetail.setName(serviceRewardPunishDetail.getName());
        newRewardPunishDetail.setLevel(serviceRewardPunishDetail.getLevel());
        newRewardPunishDetail.setRole(serviceRewardPunishDetail.getRole());
        newRewardPunishDetail.setPlatformCode(serviceRewardPunishDetail.getPlatformCode());
        newRewardPunishDetail.setViolateValue(serviceRewardPunishDetail.getViolateValue());
        newRewardPunishDetail.setDeductDate(serviceRewardPunishDetail.getDeductDate());
        newRewardPunishDetail.setMoney(serviceRewardPunishDetail.getMoney());
        newRewardPunishDetail.setDealTypeId(serviceRewardPunishDetail.getDealTypeId());
        newRewardPunishDetail.setAgentId(serviceRewardPunishDetail.getAgentId());
        newRewardPunishDetail.setAccount(serviceRewardPunishDetail.getAccount());
        newRewardPunishDetail.setRemark(serviceRewardPunishDetail.getRemark());
        newRewardPunishDetail.setStatus(RewardPunishStatusEnum.REVOKE_UPDATE.getStatus());
        newRewardPunishDetail.setDeleteType(serviceRewardPunishDetail.getDeleteType());
        newRewardPunishDetail.setRevokeType(RewardPunishRevokeTypeEnum.REVOKE_YES.getStatus());
        newRewardPunishDetail.setProfitType(ProfitTypeEnum.rewards_pt_in.getCode());
        newRewardPunishDetail.setRelateId(serviceRewardPunishDetail.getId());
        newRewardPunishDetail.setBeforeMoney(beforeMoney);
        newRewardPunishDetail.setLastMoney(lastMoney);
        newRewardPunishDetail.setCreatedTime(nowTime);
        newRewardPunishDetail.setCreateBy(updateBy);
        newRewardPunishDetail.setSubmitTime(serviceRewardPunishDetail.getSubmitTime());
        newRewardPunishDetail.setDoneTime(serviceRewardPunishDetail.getDoneTime());
        newRewardPunishDetail.setDealBy(serviceRewardPunishDetail.getDealBy());
        newRewardPunishDetail.setRevokeTime(nowTime);
        newRewardPunishDetail.setUpdateBy(updateBy);
        newRewardPunishDetail.setApplyNo(applyNoNew);
        this.save(newRewardPunishDetail);
    }

    /**
     * 获取申请单号
     */
    private String creatApplyNo() {
        //生成两位随机数
        Random random = new Random();
        int number = random.nextInt(90) + 10;

        //获取年份
        String yearAll = DateTimeFormatter.ofPattern("yyyy").format(LocalDateTime.now());
        String year = yearAll.substring(0, 2);

        return "K" + year + DateTimeFormatter.ofPattern("MMddHHmmss").format(LocalDateTime.now()) + number;
    }

    /**
     * 根据申请单号删除申请单
     *
     * @param applyNo 申请单
     * @param operate 操作人
     */
    @Override
    public void delApplyByApplyId(String applyNo, String operate) {
        //删除成功计数
        //校验该申请单是否存在，且是否为已创建状态或审核拒绝状态
        QueryWrapper<ServiceRewardPunishDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("apply_no", applyNo);
        List<ServiceRewardPunishDetail> resultList = this.list(queryWrapper);
        if (resultList.size() > SPLIT_MAX_NUM) {
            for (int i = 0; i < resultList.size(); i = i + SPLIT_MAX_NUM) {
                List<ServiceRewardPunishDetail> subApplyList = resultList.stream().skip(i).limit(SPLIT_MAX_NUM)
                        .collect(Collectors.toList());
                for (ServiceRewardPunishDetail serviceRewardPunishDetail : subApplyList) {
                    delApplyByApplyNoCommon(serviceRewardPunishDetail, operate);
                }
            }
        } else {
            for (ServiceRewardPunishDetail serviceRewardPunishDetail : resultList) {
                delApplyByApplyNoCommon(serviceRewardPunishDetail, operate);
            }
        }
    }

    /**
     * 根据申请单号提交申请单
     *
     * @param applyNo 申请单
     * @param operate 操作人
     */
    @Override
    public void submitApplyByApplyId(String applyNo, String operate) {
        //1、判断该申请单号是否已存在
        QueryWrapper<ServiceRewardPunishDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("apply_no", applyNo);
        List<ServiceRewardPunishDetail> submitList = this.list(queryWrapper);
        if (CollectionUtil.isEmpty(submitList)) {
            log.info("[财务管理后台][批量提交申请单][提交失败,该申请单不存在]");
            throw new ServiceException("该申请单不存在");
        }
        //切割list
        if (submitList.size() > SPLIT_MAX_NUM) {
            for (int i = 0; i < submitList.size(); i = i + SPLIT_MAX_NUM) {
                List<ServiceRewardPunishDetail> submitApplyList = submitList.stream().skip(i).limit(SPLIT_MAX_NUM)
                        .collect(Collectors.toList());
                //循环提交
                for (ServiceRewardPunishDetail serviceRewardPunishDetail : submitApplyList) {
                    submitApplyByApplyNoCommon(serviceRewardPunishDetail, operate);
                }
            }
        } else {
            for (ServiceRewardPunishDetail serviceRewardPunishDetail : submitList) {
                submitApplyByApplyNoCommon(serviceRewardPunishDetail, operate);
            }
        }
    }

    /**
     * 根据申请id删除申请单
     *
     * @param id      申请id
     * @param operate 操作人
     */
    @Override
    public void delApplyById(long id, String applyNo, String operate) {
        //1、判断该申请单是否存在
        QueryWrapper<ServiceRewardPunishDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        queryWrapper.eq("apply_no", applyNo);
        ServiceRewardPunishDetail serviceRewardPunishDetail = this.getOne(queryWrapper);
        if (serviceRewardPunishDetail == null) {
            log.info("[财务管理后台][奖惩申请页面][单个删除申请单,删除失败，该申请单不存在,申请id:{},申请单号:{}]", id, applyNo);
            throw new ServiceException("删除失败！该申请单不存在!");
        }
        //2、校验该申请单是否可删除 只有草稿态、拒绝态、拒绝编辑态可删除
        if (!RewardPunishStatusEnum.CREAT.getStatus().equals(serviceRewardPunishDetail.getStatus()) && !RewardPunishStatusEnum.REJECT.getStatus().equals(serviceRewardPunishDetail.getStatus()) && !RewardPunishStatusEnum.REJECT_UPDATE.getStatus().equals(serviceRewardPunishDetail.getStatus())) {
            log.info("[财务管理后台][奖惩申请页面][单个删除申请单,删除失败，该申请单状态为：{}不可删除,申请id:{},申请单号:{}]", serviceRewardPunishDetail.getStatus(), id, applyNo);
            throw new ServiceException("提交失败！该申请单不可删除!");
        }
        //3、校验该申请单是否已被删除
        if (RewardPunishApplyDeleteStatus.CHECKING.getStatus().equals(serviceRewardPunishDetail.getDeleteType())) {
            log.info("[财务管理后台][奖惩申请页面][单个删除申请单,删除失败，该申请单已删除不可重复删除,申请id:{},申请单号:{}]", id, applyNo);
            throw new ServiceException("删除失败！该申请单已删除不可重复删除!");
        }
        //更新状态
        ServiceRewardPunishDetail updateDetail = new ServiceRewardPunishDetail();
        updateDetail.setDeleteType(RewardPunishApplyDeleteStatus.CHECKING.getStatus());
        updateDetail.setUpdateBy(operate);
        UpdateWrapper<ServiceRewardPunishDetail> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", serviceRewardPunishDetail.getId());
        updateWrapper.eq("apply_no", serviceRewardPunishDetail.getApplyNo());
        updateWrapper.eq("status", serviceRewardPunishDetail.getStatus());
        updateWrapper.eq("delete_type", RewardPunishApplyDeleteStatus.CREAT.getStatus());
        boolean result = this.update(updateDetail, updateWrapper);
        if (result) {
            if (RewardPunishStatusEnum.REJECT.getStatus().equals(serviceRewardPunishDetail.getStatus()) || RewardPunishStatusEnum.REJECT_UPDATE.getStatus().equals(serviceRewardPunishDetail.getStatus())) {
                //如果状态为已拒绝，且更新状态成功，则给用户发送短信和站内信
                String messageContent = "尊敬的用户，您好。您的异议已审核通过，相应的违约金扣除决定已撤销，请知悉。";
                log.info("[财务管理后台][单个删除申请单][给idCode:{}用户发送短信:{}]", serviceRewardPunishDetail.getIdCode(), messageContent);
                try {
                    userMessageClient.rewardSendMobileMessageByTemplate(serviceRewardPunishDetail.getIdCode(), MessageTemplateIdEnum.ABM.getCode(), messageContent);
                    //给用户发送站内信，判断用户是否为ABM用户
                    if (SourceTypeEnum.ABM.getMsg().equals(serviceRewardPunishDetail.getPlatformCode())) {
                        userMessageClient.sendDtServiceFeeMessage(serviceRewardPunishDetail.getIdCode(), "违约金处理提示",
                                "尊敬的用户，您好。您的异议已审核通过，相应的违约金扣除决定已撤销，请知悉。", true, true, false);
                    }
                } catch (Exception e) {
                    log.error("[财务管理后台][单个删除申请单][给用户发送消息失败]", e);
                }
            }
        }
    }

    @Override
    public PunishApplyImportTaskResult importPunishApplyTask(int allSize, AdminPunishImport adminPunishImport) {
        ServiceTask task = new ServiceTask();
        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        task.setTaskNo(String.valueOf(IdWorker.getId())).setTaskKey(now + "_" + "奖惩申请页导入")
                .setBizType(TaskBizType.TYPE_1.getType()).
                setTaskSize(allSize).setTaskStatus(1).setTaskApplicant(adminPunishImport.getOperate())
                .setCreateTime(LocalDateTime.now()).setUpdateTime(LocalDateTime.now());
        int num = serviceTaskMapper.insert(task);
        PunishApplyImportTaskResult taskResult = new PunishApplyImportTaskResult();
        if (num > 0) {
            taskResult.setTaskResult(true);
            taskResult.setTaskNo(task.getTaskNo());
            taskResult.setTaskKey(task.getTaskKey());
            return taskResult;
        }
        taskResult.setTaskResult(false);
        taskResult.setErrorMsg("创建任务失败，请稍后重试");
        return taskResult;
    }

    /**
     * 导入
     *
     * @param taskNo            任务编号
     * @param punishApplyInfo   信息
     * @param adminPunishImport 导入信息
     */
    @Override
    public void importPunishApply(String taskNo, List<String[]> punishApplyInfo, AdminPunishImport adminPunishImport) {
        ServiceTask updateTask = new ServiceTask();
        updateTask.setTaskNo(taskNo);
        //错误信息存储errorMsgList
        List<String> errorMsg = Lists.newArrayList();
        //启始行
        int successCount = 0;
        if (punishApplyInfo.size() > 5000) {
            throw new ServiceException("导入数据需要小于5000条!");
        }
        try {
            int checkSize = punishApplyInfo.size() - 1;
            for (int i = 3; i < punishApplyInfo.size(); i++) {
                ServiceTask task = new ServiceTask();
                task.setDealSize(checkSize - i).setUpdateTime(LocalDateTime.now());
                serviceTaskMapper.update(task, new UpdateWrapper<>(updateTask));
                String[] punishApply = punishApplyInfo.get(i);
                int lineNumber = (i + 1);
                String idCode;
                String mobile;
                String dealValue;
                String money;
                String platformCode;
                String deductDate;
                try {
                    if (StringUtils.isEmpty(punishApply[0]) || StringUtils.isEmpty(punishApply[1]) || StringUtils.isEmpty(punishApply[5]) || StringUtils.isEmpty(punishApply[7]) || StringUtils.isEmpty(punishApply[8]) || StringUtils.isEmpty(punishApply[9])) {
                        errorMsg.add("第" + lineNumber + "行必填信息为空;");
                        continue;
                    }
                    //取出各值，方便后面校验
                    idCode = StringUtils.deleteWhitespace(punishApply[0]);
                    mobile = StringUtils.deleteWhitespace(punishApply[1]);
                    dealValue = punishApply[5];
                    money = StringUtils.deleteWhitespace(punishApply[7]);
                    platformCode = StringUtils.deleteWhitespace(punishApply[8]);
                    deductDate = punishApply[9];
                } catch (Exception e) {
                    log.info("[财务管理后台][奖惩审核页申请单导入][第" + lineNumber + "行数据处理失败,必填参数缺失]");
                    errorMsg.add("第" + lineNumber + "行数据处理失败,必填参数缺失");
                    continue;
                }
                //校验扣除日期是否符合YYYY-MM格式
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
                try {
                    format.parse(deductDate);
                } catch (Exception e) {
                    log.info("[财务管理后台][奖惩审核页申请单导入][第" + lineNumber + "行数据处理失败,扣除期间不正确,值为:{}]", deductDate);
                    errorMsg.add("第" + lineNumber + "行数据处理失败,扣除期间不正确");
                    continue;
                }
                //校验该用户账户是否存在
                CoverChargeEnum.ServiceAccountType serviceAccountType = CoverChargeEnum.ServiceAccountType.getServiceAccountTypeByPlatform(platformCode);
                if (serviceAccountType == null) {
                    log.info("[财务管理后台][奖惩审核页申请单导入][第" + lineNumber + "行数据处理失败,该账户不存在,idCode:{},platformCode:{}]", idCode, platformCode);
                    errorMsg.add("第" + lineNumber + "行数据处理失败,idCode为" + idCode + ",并且账户为" + platformCode + "的账户不存在");
                    continue;
                }
                int accountType = serviceAccountType.getCode();
                ServiceAccount serviceAccount = serviceAccountService.judgeAccountExis(accountType, Integer.parseInt(idCode));
                if (serviceAccount == null) {
                    log.info("[财务管理后台][奖惩审核页申请单导入][第" + lineNumber + "行数据处理失败,该账户不存在,idCode:{},accountType:{}]", idCode, accountType);
                    errorMsg.add("第" + lineNumber + "行数据处理失败,idCode为" + idCode + ",并且账户为" + accountType + "的账户不存在");
                    continue;
                }
                //根据处理类性值找到处理类型id
                QueryWrapper<ServiceRewardPunishCategory> categoryQueryWrapper = new QueryWrapper<>();
                categoryQueryWrapper.eq("title", dealValue);
                categoryQueryWrapper.eq("parent_id", RewardPunishCategoryEnum.DEAL.getStatus());
                categoryQueryWrapper.eq("status", RewardPunishCategoryStatusEnum.ENABLE.getStatus());
                ServiceRewardPunishCategory serviceRewardPunishCategory = serviceRewardPunishCategoryService.getOne(categoryQueryWrapper);
                if (serviceRewardPunishCategory == null) {
                    log.error("[财务管理后台][奖惩申请页导入][该条处理失败,当前处理状态:{}不存在,用户idCode:{}]", dealValue, idCode);
                    errorMsg.add("第" + lineNumber + "行获取处理状态失败,当前处理状态为" + dealValue + "不存在或已禁用");
                    continue;
                }
                BigDecimal checkMoney = new BigDecimal(money);
                //校验金额是否大于0
                if (checkMoney.compareTo(new BigDecimal("0")) < 1) {
                    log.info("[财务管理后台][奖惩申请页面][新建申请单失败,金额填写错误！金额:{},idCode：{}]", checkMoney, idCode);
                    errorMsg.add("第" + lineNumber + "行添加失败,金额必须大于0!");
                    continue;
                }
                //校验用户信息
                ServiceRewardPunishDetail serviceRewardPunishDetail = new ServiceRewardPunishDetail();
                try {
                    UserInfo userInfo = userDocService.searchUserByIdCodeOrMobile(new UserIdCode(Long.parseLong(idCode)),null);
                    if (userInfo == null) {
                        log.info("[财务管理后台][奖惩申请页导入][获取用户信息失败,未查询到该用户信息]");
                        errorMsg.add("第" + lineNumber + "行获取用户信息失败,未查询到idCode为" + idCode + "用户信息;");
                        continue;
                    }
                    //比对注册手机号是否一致
                    if (!mobile.equals(userInfo.getMobile())) {
                        log.info("[财务管理后台][奖惩申请页导入][第" + lineNumber + "条数据处理失败,该条数据用户手机号不匹配]");
                        errorMsg.add("第" + lineNumber + "行数据处理失败,该条数据idCode为" + idCode + "用户手机号不正确");
                        continue;
                    }
                    serviceRewardPunishDetail.setMobile(userInfo.getMobile());
                    serviceRewardPunishDetail.setName(userInfo.getName());

//                    Result<ProviderExt> result = brandProviderLevelServer.getByIdCodeAndType(Integer.parseInt(idCode), SourceTypeEnum.getSourceCode(platformCode));
//                    if (result == null || result.getData() == null) {
//                        log.info("[财务管理后台][奖惩申请页导入][第" + lineNumber + "条数据处理失败,未查询到该用户的等级]");
//                        errorMsg.add("第" + lineNumber + "行数据处理失败,未查询到idCode为" + idCode + "的用户的等级");
//                        continue;
//                    }
//                    serviceRewardPunishDetail.setLevel(UserLevelEnum.getMsg(result.getData().getBrandProviderLevel()));
//                    JsonResult<RoleDTO> memberResult = roleFeign.getByIdCode(Long.parseLong(idCode));
//                    if (memberResult == null || memberResult.getData() == null) {
//                        log.info("[财务管理后台][奖惩申请页导入][第" + lineNumber + "条数据处理失败,未查询到该用户的角色]");
//                        errorMsg.add("第" + lineNumber + "条数据处理失败,未查询到该用户的角色");
//                        continue;
//                    }
//                    serviceRewardPunishDetail.setRole(RoleEnum.fromCode(memberResult.getData().getRoleEnum()).getDesc());
                } catch (Exception e) {
                    log.error("[支付后台][奖惩申请页面][用户信息查询失败,用户idCod:{}]", serviceRewardPunishDetail.getIdCode(), e);
                    errorMsg.add("第" + lineNumber + "行数据处理失败,有异常抛出,未查询到idCode为" + idCode + "的用户的信息");
                    continue;
                }
                serviceRewardPunishDetail.setIdCode(Integer.parseInt(idCode));
                serviceRewardPunishDetail.setApplyNo(adminPunishImport.getApplyNo());
                serviceRewardPunishDetail.setPlatformCode(platformCode);
                serviceRewardPunishDetail.setAccount("服务费账户");
                if (StringUtils.isNotBlank(punishApply[6])) {
                    serviceRewardPunishDetail.setViolateValue(punishApply[6]);
                }
                serviceRewardPunishDetail.setDealTypeId(serviceRewardPunishCategory.getId());
                serviceRewardPunishDetail.setMoney(checkMoney);
                serviceRewardPunishDetail.setDeductDate(deductDate);
                try {
                    if (StringUtils.isNotBlank(punishApply[10])) {
                        String agentName = punishApply[10];
                        QueryWrapper<ServiceRewardPunishCategory> agentQueryWrapper = new QueryWrapper<>();
                        agentQueryWrapper.eq("title", agentName);
                        agentQueryWrapper.eq("parent_id", RewardPunishCategoryEnum.Agent.getStatus());
                        categoryQueryWrapper.eq("status", RewardPunishCategoryStatusEnum.ENABLE.getStatus());
                        ServiceRewardPunishCategory agentCategory = serviceRewardPunishCategoryService.getOne(agentQueryWrapper);
                        if (agentCategory == null) {
                            log.error("[财务管理后台][奖惩申请页导入][该条处理失败,当前经办人:{}不存在,用户idCode:{}]", dealValue, idCode);
                            errorMsg.add("第" + lineNumber + "行获取经办人失败,当前经办人不存在或已禁用");
                            continue;
                        }
                        serviceRewardPunishDetail.setAgentId(agentCategory.getId());
                    }
                    if (StringUtils.isNotBlank(punishApply[11])) {
                        serviceRewardPunishDetail.setViolateValue(punishApply[11]);
                    }
                } catch (Exception e) {
                    log.info("处理未填写异常");
                }
                serviceRewardPunishDetail.setApplyNo(adminPunishImport.getApplyNo());
                serviceRewardPunishDetail.setProfitType(ProfitTypeEnum.rewards_pt_out.getCode());
                serviceRewardPunishDetail.setStatus(RewardPunishStatusEnum.CREAT.getStatus());
                serviceRewardPunishDetail.setCreatedTime(LocalDateTime.now());
                serviceRewardPunishDetail.setCreateBy(adminPunishImport.getOperate());
                //做更新处理
                boolean result = this.save(serviceRewardPunishDetail);
                if (result) {
                    successCount++;
                }
            }
            ServiceTask task = new ServiceTask();
            task.setSuccessSize(successCount).setFailSize(punishApplyInfo.size() - 3 - successCount)
                    .setTaskStatus(2).setUpdateTime(LocalDateTime.now());
            if (errorMsg.size() <= 10) {
                task.setTaskErrorMsg(StringUtils.join(errorMsg.toArray(), ""));
            } else {
                //上传文件
                task.setTaskErrorMsg("错误信息太多，只取前30条:" + StringUtils.join(errorMsg.subList(0, 30), "\n"));
                ByteArrayInputStream inputStream = new ByteArrayInputStream(StringUtils.join(errorMsg.toArray(), "\n").getBytes());
                String fileKey = OssUtil.uploadObjectByInputStream(inputStream, "errorMsg", updateTask.getTaskNo() + ".txt");
                task.setDownloadUrl(fileKey);
            }
            serviceTaskMapper.update(task, new UpdateWrapper<>(updateTask));
        } catch (Exception e) {
            log.error("导入奖惩申请单异常:", e);
            ServiceTask task = new ServiceTask();
            String error = "导入失败,请确认导入数据是否正确！导入奖惩申请单异常原因:" + e.getMessage().substring(0, Math.min(e.getMessage().length(), 300));
            task.setSuccessSize(successCount).setFailSize(punishApplyInfo.size() - 3 - successCount).setTaskErrorMsg(error).setTaskStatus(3)
                    .setUpdateTime(LocalDateTime.now());
            serviceTaskMapper.update(task, new UpdateWrapper<>(updateTask));
        }
    }

    /**
     * 编辑申请单
     *
     * @param adminPunishApplySave 更新实体
     */
    @Override
    public void updateApply(AdminPunishApplySave adminPunishApplySave) {
        //1、判断该申请单是否存在
        QueryWrapper<ServiceRewardPunishDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("apply_no", adminPunishApplySave.getApplyNo());
        queryWrapper.eq("id", adminPunishApplySave.getId());
        ServiceRewardPunishDetail serviceRewardPunishDetail = this.getOne(queryWrapper);
        //2、判断该单号是否存在
        if (serviceRewardPunishDetail == null) {
            log.info("[财务管理后台][奖惩申请页面][编辑申请单失败,该申请单号不存在！applyNo:{}]", adminPunishApplySave.getApplyNo());
            throw new ServiceException("该申请单号不存在！");
        }
        //3、判断该单号是否已被删除
        if (RewardPunishApplyDeleteStatus.CHECKING.getStatus().equals(serviceRewardPunishDetail.getDeleteType())) {
            log.info("[财务管理后台][奖惩申请页面][编辑申请单失败,该申请单已被删除不可编辑！applyNo:{},status:{}]", adminPunishApplySave.getApplyNo(), serviceRewardPunishDetail.getStatus());
            throw new ServiceException("该申请单已被删除不可编辑！");
        }
        //4、判断该申请单状态是否为可编辑态  只有草稿态和被驳回状态可以编辑
        if (!RewardPunishStatusEnum.CREAT.getStatus().equals(serviceRewardPunishDetail.getStatus()) && !RewardPunishStatusEnum.REJECT.getStatus().equals(serviceRewardPunishDetail.getStatus()) && !RewardPunishStatusEnum.REJECT_UPDATE.getStatus().equals(serviceRewardPunishDetail.getStatus())) {
            log.info("[财务管理后台][奖惩申请页面][编辑申请单失败,该申请单状态不可编辑！applyNo:{},status:{}]", adminPunishApplySave.getApplyNo(), serviceRewardPunishDetail.getStatus());
            throw new ServiceException("该申请单状态不可编辑！");
        }
        //5、校验处理状态id是否存在
        ServiceRewardPunishCategory dealCategory = serviceRewardPunishCategoryService.getInfoByStatus(adminPunishApplySave.getDealId(), RewardPunishCategoryStatusEnum.ENABLE.getStatus());
        if (dealCategory == null) {
            log.info("[财务管理后台][奖惩申请页面][编辑申请单失败,该处理类型不存在,处理类型id:{}]", adminPunishApplySave.getDealId());
            throw new ServiceException("修改失败,该处理类型不存在或已被禁用！");
        }
        //6、校验经办人id,是否存在
        if (adminPunishApplySave.getAgentId() != null) {
            ServiceRewardPunishCategory agentCategory = serviceRewardPunishCategoryService.getInfoByStatus(adminPunishApplySave.getAgentId(), RewardPunishCategoryStatusEnum.ENABLE.getStatus());
            if (agentCategory == null) {
                log.info("[财务管理后台][奖惩申请页面][编辑申请单失败,该经办人不存在,经办人类型id:{}]", adminPunishApplySave.getDealId());
                throw new ServiceException("修改失败,该经办人不存在或已被禁用！");
            }
        }
        //7、校验账户是否存在
        QueryWrapper<ServiceAccount> accountQueryWrapper = new QueryWrapper<>();
        accountQueryWrapper.eq("id_code", adminPunishApplySave.getIdCode());
        CoverChargeEnum.ServiceAccountType serviceAccountType = CoverChargeEnum.ServiceAccountType.getServiceAccountTypeByPlatform(adminPunishApplySave.getPlatformCode());
        if (serviceAccountType == null) {
            log.info("[财务管理后台][奖惩申请页面][编辑申请单失败,该账户不存在,申请idCode：{}]", adminPunishApplySave.getIdCode());
            throw new ServiceException("修改失败！该账户不存在!");
        }
        int accountType = serviceAccountType.getCode();
        accountQueryWrapper.eq("account_type", accountType);
        ServiceAccount serviceAccount = serviceAccountService.getOne(accountQueryWrapper);
        if (serviceAccount == null) {
            log.info("[财务管理后台][奖惩申请页面][编辑申请单失败,该账户不存在idCode:{}]", adminPunishApplySave.getIdCode());
            throw new ServiceException("修改失败！该账户不存在！");
        }
        //8、校验金额是否大于0
        if (adminPunishApplySave.getMoney().compareTo(new BigDecimal("0")) < 1) {
            log.info("[财务管理后台][奖惩申请页面][编辑申请单失败,金额填写错误！金额:{}]", adminPunishApplySave.getMoney());
            throw new ServiceException("修改失败！金额填写错误！");
        }
        //更新
        ServiceRewardPunishDetail updatePunishDetail = new ServiceRewardPunishDetail();
        updatePunishDetail.setId(adminPunishApplySave.getId());
        updatePunishDetail.setProfitType(adminPunishApplySave.getProfitType());
        updatePunishDetail.setRemark(adminPunishApplySave.getRemark());
        updatePunishDetail.setDeductDate(adminPunishApplySave.getDeductDate());
        updatePunishDetail.setMoney(adminPunishApplySave.getMoney());
        updatePunishDetail.setViolateValue(adminPunishApplySave.getViolateValue());
        updatePunishDetail.setDealTypeId(adminPunishApplySave.getDealId());
        updatePunishDetail.setAgentId(adminPunishApplySave.getAgentId());
        updatePunishDetail.setPlatformCode(adminPunishApplySave.getPlatformCode());
        updatePunishDetail.setUpdateBy(adminPunishApplySave.getOperate());
        if (RewardPunishStatusEnum.REJECT.getStatus().equals(serviceRewardPunishDetail.getStatus())) {
            updatePunishDetail.setStatus(RewardPunishStatusEnum.REJECT_UPDATE.getStatus());
        } else {
            updatePunishDetail.setStatus(serviceRewardPunishDetail.getStatus());
        }
        UpdateWrapper<ServiceRewardPunishDetail> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", adminPunishApplySave.getId());
        updateWrapper.eq("apply_no", adminPunishApplySave.getApplyNo());
        updateWrapper.eq("status", serviceRewardPunishDetail.getStatus());
        updateWrapper.eq("delete_type", RewardPunishApplyDeleteStatus.CREAT.getStatus());
        boolean result = this.update(updatePunishDetail, updateWrapper);
        if (!result) {
            log.info("[财务管理后台][奖惩申请页面][编辑申请单失败,该申请单不可编辑!applyNo:{},status:{}]", adminPunishApplySave.getApplyNo(), serviceRewardPunishDetail.getStatus());
            throw new ServiceException("该单不可编辑,有疑问请联系开发人员!");
        }
    }

    /**
     * 根据申请id提交申请单
     *
     * @param id      申请主键id
     * @param applyNo 申请单号
     * @param operate 操作人
     */
    @Override
    public void submitApplyById(long id, String applyNo, String operate) {
        //1、判断该申请单是否存在
        QueryWrapper<ServiceRewardPunishDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        queryWrapper.eq("apply_no", applyNo);
        ServiceRewardPunishDetail serviceRewardPunishDetail = this.getOne(queryWrapper);
        if (serviceRewardPunishDetail == null) {
            log.info("[财务管理后台][奖惩申请页面][单个提交申请单,提交失败，该申请单不存在,申请id:{},申请单号:{}]", id, applyNo);
            throw new ServiceException("提交失败！该申请单不存在!");
        }
        //2、校验该申请单是否可提交 只有草稿态才可提交
        if (!RewardPunishStatusEnum.CREAT.getStatus().equals(serviceRewardPunishDetail.getStatus()) && !RewardPunishStatusEnum.REJECT_UPDATE.getStatus().equals(serviceRewardPunishDetail.getStatus())) {
            log.info("[财务管理后台][奖惩申请页面][单个提交申请单,提交失败，该申请单状态为：{}不可提交,申请id:{},申请单号:{}]", serviceRewardPunishDetail.getStatus(), id, applyNo);
            throw new ServiceException("提交失败！该申请单不可提交!");
        }
        //3、校验该申请单是否已被删除
        if (RewardPunishApplyDeleteStatus.CHECKING.getStatus().equals(serviceRewardPunishDetail.getDeleteType())) {
            log.info("[财务管理后台][奖惩申请页面][单个提交申请单,提交失败，该申请单已删除不可提交,申请id:{},申请单号:{}]", id, applyNo);
            throw new ServiceException("提交失败！该申请单已被删除不可提交!");
        }
        //更新状态
        ServiceRewardPunishDetail updateDetail = new ServiceRewardPunishDetail();
        updateDetail.setStatus(RewardPunishStatusEnum.CHECKING.getStatus());
        updateDetail.setUpdateBy(operate);
        updateDetail.setSubmitTime(LocalDateTime.now());
        UpdateWrapper<ServiceRewardPunishDetail> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", serviceRewardPunishDetail.getId());
        updateWrapper.eq("apply_no", serviceRewardPunishDetail.getApplyNo());
        updateWrapper.eq("status", serviceRewardPunishDetail.getStatus());
        updateWrapper.eq("delete_type", RewardPunishApplyDeleteStatus.CREAT.getStatus());
        boolean result = this.update(updateDetail, updateWrapper);
        if (result && RewardPunishStatusEnum.CREAT.getStatus().equals(serviceRewardPunishDetail.getStatus())) {
            //如果更新状态成功，则给用户发送短信和站内信
            //获取用户扣除期间
            String messageContent = "尊敬的用户，您好。根据您" + serviceRewardPunishDetail.getDeductDate() + "月份的违规记录，将于7个工作日内扣除相应金额：" + serviceRewardPunishDetail.getMoney() + "元，如您有异议请及时联系当时处理违规的合规人员进一步反馈，请知悉。";
            log.info("[财务管理后台][单个提交申请单][给idCode为：{}的用户发送短信:{}]", serviceRewardPunishDetail.getIdCode(), messageContent);
            try {
                userMessageClient.rewardSendMobileMessageByTemplate(serviceRewardPunishDetail.getIdCode(), MessageTemplateIdEnum.ABM.getCode(), messageContent);
                //给用户发送站内信，判断用户是否为ABM用户
                if (SourceTypeEnum.ABM.getMsg().equals(serviceRewardPunishDetail.getPlatformCode())) {
                    userMessageClient.sendDtServiceFeeMessage(serviceRewardPunishDetail.getIdCode(), "违约金处理提示",
                            "尊敬的用户，您好。根据您" + serviceRewardPunishDetail.getDeductDate() + "月份的违规记录，将于7个工作日内扣除相应金额：" + serviceRewardPunishDetail.getMoney() + "元，如您有异议请及时联系当时处理违规的合规人员进一步反馈，请知悉。", true, true, false);
                }
            } catch (Exception e) {
                log.error("[财务管理后台][单个提交申请单][给用户发送消息失败]", e);
            }

        }
    }

    /**
     * 删除申请单发送站内信和短信
     *
     * @param serviceRewardPunishDetail 用户信息
     * @param operate                   操作人
     */
    void delApplyByApplyNoCommon(ServiceRewardPunishDetail serviceRewardPunishDetail, String operate) {
        //判断该单是否已被删除
        if (RewardPunishApplyDeleteStatus.CHECKING.getStatus().equals(serviceRewardPunishDetail.getDeleteType())) {
            log.info("[财务管理后台][批量删除申请单][该单已删除,不可重复删除]");
            return;
        }
        //判断是否为可删除状态(只有草稿态和被驳回态可以删除)
        if (!RewardPunishStatusEnum.CREAT.getStatus().equals(serviceRewardPunishDetail.getStatus())
                && !RewardPunishStatusEnum.REJECT.getStatus().equals(serviceRewardPunishDetail.getStatus())
                && !RewardPunishStatusEnum.REJECT_UPDATE.getStatus().equals(serviceRewardPunishDetail.getStatus())) {
            log.info("[财务管理后台][批量删除申请单][该单删除失败,状态为:{},不可删除]", serviceRewardPunishDetail.getStatus());
            return;
        }
        //更新状态
        ServiceRewardPunishDetail updateDetail = new ServiceRewardPunishDetail();
        updateDetail.setDeleteType(RewardPunishApplyDeleteStatus.CHECKING.getStatus());
        updateDetail.setUpdateBy(operate);
        UpdateWrapper<ServiceRewardPunishDetail> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", serviceRewardPunishDetail.getId());
        updateWrapper.eq("apply_no", serviceRewardPunishDetail.getApplyNo());
        updateWrapper.eq("status", serviceRewardPunishDetail.getStatus());
        updateWrapper.eq("delete_type", RewardPunishApplyDeleteStatus.CREAT.getStatus());
        boolean result = this.update(updateDetail, updateWrapper);
        if (result) {
            if (RewardPunishStatusEnum.REJECT.getStatus().equals(serviceRewardPunishDetail.getStatus()) || RewardPunishStatusEnum.REJECT_UPDATE.getStatus().equals(serviceRewardPunishDetail.getStatus())) {
                //如果状态为已拒绝，且更新状态成功，则给用户发送短信和站内信
                String messageContent = "尊敬的用户，您好。您的异议已审核通过，相应的违约金扣除决定已撤销，请知悉。";
                log.info("[财务管理后台][批量删除申请单][给用户发送短信:{}]", messageContent);
                try {
                    userMessageClient.rewardSendMobileMessageByTemplate(serviceRewardPunishDetail.getIdCode(), MessageTemplateIdEnum.ABM.getCode(), messageContent);
                    //给用户发送站内信，判断用户是否为ABM用户
                    if (SourceTypeEnum.ABM.getMsg().equals(serviceRewardPunishDetail.getPlatformCode())) {
                        userMessageClient.sendDtServiceFeeMessage(serviceRewardPunishDetail.getIdCode(), "违约金处理提示",
                                "尊敬的用户，您好。您的异议已审核通过，相应的违约金扣除决定已撤销，请知悉。", true, true, false);
                    }
                } catch (Exception e) {
                    log.error("[财务管理后台][批量删除申请单][给用户发送消息失败]", e);
                }
            }

        }
    }

    /**
     * 提交申请单发送站内信和短信
     *
     * @param serviceRewardPunishDetail 用户信息
     * @param operate                   操作人
     */
    void submitApplyByApplyNoCommon(ServiceRewardPunishDetail serviceRewardPunishDetail, String operate) {
        //判断该申请单状态是否为可提交，如果不可提交则继续循环
        if (!RewardPunishStatusEnum.CREAT.getStatus().equals(serviceRewardPunishDetail.getStatus())
                && !RewardPunishStatusEnum.REJECT_UPDATE.getStatus().equals(serviceRewardPunishDetail.getStatus())) {
            log.info("[财务管理后台][批量提交申请单][改单提交失败,状态为:{},不可提交]", serviceRewardPunishDetail.getStatus());
            return;
        }
        //判断改单是否为已删除状态，若已删除则不可提交
        if (RewardPunishApplyDeleteStatus.CHECKING.getStatus().equals(serviceRewardPunishDetail.getDeleteType())) {
            log.info("[财务管理后台][批量提交申请单][该单已被删除,不可提交,删除状态：{}]", serviceRewardPunishDetail.getDeleteType());
            return;
        }
        //更新状态
        ServiceRewardPunishDetail updateDetail = new ServiceRewardPunishDetail();
        updateDetail.setStatus(RewardPunishStatusEnum.CHECKING.getStatus());
        updateDetail.setUpdateBy(operate);
        updateDetail.setSubmitTime(LocalDateTime.now());
        UpdateWrapper<ServiceRewardPunishDetail> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", serviceRewardPunishDetail.getId());
        updateWrapper.eq("apply_no", serviceRewardPunishDetail.getApplyNo());
        updateWrapper.eq("status", serviceRewardPunishDetail.getStatus());
        updateWrapper.eq("delete_type", RewardPunishApplyDeleteStatus.CREAT.getStatus());
        boolean result = this.update(updateDetail, updateWrapper);
        if (result && RewardPunishStatusEnum.CREAT.getStatus().equals(serviceRewardPunishDetail.getStatus())) {
            //如果更新状态成功，则给用户发送短信和站内信
            //获取用户扣除期间
            String messageContent = "尊敬的用户，您好。根据您" + serviceRewardPunishDetail.getDeductDate() + "月份的违规记录，将于7个工作日内扣除相应金额：" + serviceRewardPunishDetail.getMoney() + "元，如您有异议请及时联系当时处理违规的合规人员进一步反馈，请知悉。";
            log.info("[财务管理后台][批量提交申请单][给idCode为：{}的用户发送短信:{}]", serviceRewardPunishDetail.getIdCode(), messageContent);
            try {
                userMessageClient.rewardSendMobileMessageByTemplate(serviceRewardPunishDetail.getIdCode(), MessageTemplateIdEnum.ABM.getCode(), messageContent);
                //给用户发送站内信，判断用户是否为ABM用户
                if (SourceTypeEnum.ABM.getMsg().equals(serviceRewardPunishDetail.getPlatformCode())) {
                    userMessageClient.sendDtServiceFeeMessage(serviceRewardPunishDetail.getIdCode(), "违约金处理提示",
                            "尊敬的用户，您好。根据您" + serviceRewardPunishDetail.getDeductDate() + "月份的违规记录，将于7个工作日内扣除相应金额：" + serviceRewardPunishDetail.getMoney() + "元，如您有异议请及时联系当时处理违规的合规人员进一步反馈，请知悉。", true, true, false);
                }
            } catch (Exception e) {
                log.error("[财务管理后台][批量提交申请单][给用户发送消息失败]", e);
            }

        }
    }
}
